/***************************************************************************
 *   Copyright (C) 2009 by Bernhard Neuhofer   *
 *   mail@bneu.at   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef FACTORIES_H
#define FACTORIES_H

#include "abstractAdFactory.h"
#include "abstractLpFactory.h"
#include "abstractMeFactory.h"
#include "abstractSchedFactory.h"

#include "abstractAdapter.h"
#include "AbstractLp.h"
#include "modelentity.h"
#include "Scheduler.h"

#include <map>
#include <string>

/**
*@brief A Class of Factories which creates Adapters,Lps and Modelentities by name
*		uses Singleton Pattern
*/
class Factories
{
  
  
private:
Factories() {};
  Factories( const Factories&);
  Factories& operator = (const Factories &);  
  
/** Map which stores Factories of Adapters*/
map<string, AbstractAdFactory*> _ads;
/** Map which stores Factories of LPs*/
map<string, AbstractLpFactory*> _lps;
/** Map which stores Factories of ModelEntitys*/
map<string, AbstractMeFactory*> _mes;

map<string, AbstractSchedFactory*> _sched;



public:
static Factories& instance()
     {
	   static Factories _instance;
	   return _instance;
	 }
	 ~Factories() {};

/**
 * Create a Adapter of the given name
 * @param name of the Adapter
 * @return 
 */
virtual AbstractAdapter* createAd(string name);

/**
 * Create a LP of the given name
 * @param name of the LP
 * @param id  the id of the LP
 * @return 
 */
virtual AbstractLp* createLp(string name,unsigned int id);

/**
 * Create a ModelEntity of the given name
 * @param name of the ModelEntity
 * @return 
 */
virtual ModelEntity* createMe(string name,AbstractLp* assocLp,vector<unsigned int> neighbors);


/**
 * Create a Scheduler of the given name
 * @param name 
 * @return 
 */
virtual Scheduler* createSched(string name);
/**
 * Adds a factory for creation of a Adapter with a given name
 * @param adfac The AdapterFactory
 * @param name of the Adapter
 */
virtual void addAdCreator(AbstractAdFactory* adfac, string name);
/**
 * Adds a factory for creation of a LP with a given name
 * @param lpfac The LpFactory
 * @param name of the Adapter
 */
virtual void addLpCreator(AbstractLpFactory* lpfac, string name);
/**
 * Adds a factory for creation of a Me with a given name
 * @param mefac The MeFactory
 * @param name of the ModelEntity
 */
virtual void addMeCreator(AbstractMeFactory* mefac, string name);

/**
 * Adds a factory for creating of a Scheduler with a given name
 * @param schedfac The SchedFactory
 * @param name the ModelEntity
 */
virtual void addSchedCreator(AbstractSchedFactory* schedfac, string name);


/**
 * Removes a Adapter from the memory (Correct Class !!);
 * @param ad The concrete Adapter
 * @param name of the class of the adapter
 */
virtual void delAd(AbstractAdapter* ad,string name);

/**
 * Removes a LP from the memory (Find the correct Class!);
 * @param lp The concrete LP
 * @param name of the class of the LP
 */
virtual void delLp(AbstractLp* lp,string name);

/**
 * Removes a ME from the memory (find the correct class for removal!)
 * @param me the concrete ME
 * @param name of the class of the Me
 */
virtual void delMe(ModelEntity* me,string name);


/**
 * Removes a Scheduler from the memory (find the correct class for removal)
 * @param sched the conrete Scheduler
 * @param name of the class of the Scheduler
 */
virtual void delSched(Scheduler* sched,string name);
};


#endif